<template>
  <PageTable
    :search-options="options"
    :columns="columns.filter((item) => item?.checked)"
    :data-source="sourceData"
    v-model:expandedRowKeys="expandedRowKeys"
    :pagination="false"
    :loading="spinning"
    @search="onSearchData"
  >
    <template #searchCollapse>
      <AForm layout="inline" ref="formRef" :model="formState" @finish="onSearchData" @reset="onReset">
        <AFormItem label="菜单名称" name="menuName">
          <AInput v-model:value="formState.menuName" placeholder="请输入菜单名称"></AInput>
        </AFormItem>
        <AFormItem label="组件路径" name="component">
          <AInput v-model:value="formState.component" placeholder="请输入组件路径"></AInput>
        </AFormItem>
        <AFormItem label="路由地址" name="menuPath">
          <AInput v-model:value="formState.menuPath" placeholder="请输入路由地址"></AInput>
        </AFormItem>
        <AFormItem>
          <ASpace>
            <AButton html-type="reset">重置</AButton>
            <AButton type="primary" html-type="submit">搜索</AButton>
          </ASpace>
        </AFormItem>
      </AForm>
    </template>
    <template #operate>
      <ASpace>
        <AButton type="primary" ghost :icon="createVNode(PlusOutlined)" @click="onOpenAddModal">添加</AButton>
      </ASpace>
      <ASpace>
        <ATooltip title="刷新列表">
          <AButton :icon="createVNode(ReloadOutlined)" :disabled="!!timer" @click="onRefreshData">
            {{ timer || '' }}
          </AButton>
        </ATooltip>
        <ATooltip title="展开/折叠 ">
          <AButton :icon="createVNode(SwitcherOutlined)" @click="onExpandAll"></AButton>
        </ATooltip>

        <RDropdownCheckbox
          placement="bottomRight"
          v-model:value="columns"
          :fieldNames="{ label: 'title', value: 'key', checked: 'checked' }"
        >
          <AButton :icon="createVNode(AppstoreOutlined)"></AButton>
        </RDropdownCheckbox>
      </ASpace>
    </template>
    <template #bodyCell="{ column, record }">
      <component v-if="column?.key === 'menuIcon' && record[column?.key]" :is="record[column?.key]" />
    </template>
    <template #bodyActionCell="{ record }">
      <AButton
        v-show="record?.menuType !== 'BUTTON'"
        type="link"
        size="small"
        :icon="createVNode(PlusOutlined)"
        @click="() => onOpenAddModal(record)"
      >
        添加
      </AButton>
      <AButton type="link" size="small" :icon="createVNode(EditOutlined)" @click="() => onOpenEditModal(record)">
        编辑
      </AButton>
      <APopconfirm
        title="您确定删除该数据吗?"
        ok-text="是"
        cancel-text="否"
        @confirm="() => onDelete([record?.menuId])"
      >
        <AButton type="link" danger size="small" :icon="createVNode(DeleteOutlined)">删除</AButton>
      </APopconfirm>
    </template>
  </PageTable>
  <AddMenu
    :open="openAddModal"
    :init-values="initValues"
    :type-disable="menuTypeDisabled"
    @cancel="onCloseAddModal"
    @finish="onAddMenu"
  />
  <EditMenu :open="openEditModal" :menuId="menuId" @cancel="onCloseEditModal" @finish="onEditMenu" />
</template>

<script setup>
import { createVNode, ref, reactive, toValue, onBeforeMount } from 'vue';
import { PageTable } from '@/components/templates';
import { AddMenu, EditMenu } from './modules';
import { RDropdownCheckbox } from '@/components/custom';
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  AppstoreOutlined,
  ReloadOutlined,
  SwitcherOutlined
} from '@ant-design/icons-vue';
import { useFetchData, useState } from '@/hooks';
import { fetchGetMenuTree, fetchAddMenu, fetchUpdateMenu, fetchDeleteMenu } from '@/api/system/menu';
import { arrayDeepFlat } from '@/utils/array';

const options = [
  { label: '综合搜索', value: 'keyword', placeholder: '综合搜索' },
  { label: '菜单名称', value: 'menuName', placeholder: '请输入菜单名称' },
  { label: '组件路径', value: 'component', placeholder: '请输入组件路径' },
  { label: '路由地址', value: 'menuPath', placeholder: '请输入路由地址' }
];

const defaultColumns = [
  { key: 'menuName', title: '菜单名称', dataIndex: 'menuName', checked: true },
  { key: 'menuIcon', title: '图标', dataIndex: 'menuIcon', align: 'center', checked: true },
  { key: 'orderNum', title: '排序', dataIndex: 'orderNum', checked: true },
  { key: 'menuPath', title: '路由地址', dataIndex: 'menuPath', checked: true },
  { key: 'menuCode', title: '权限标识', dataIndex: 'menuCode', checked: true },
  { key: 'component', title: '组件路径', dataIndex: 'component', checked: true },
  { key: 'statusName', title: '状态', dataIndex: 'statusName', checked: true },
  { key: 'createTime', title: '创建时间', dataIndex: 'createTime', checked: true },
  { key: 'action', title: '操作', align: 'right', checked: true }
];
const columns = ref(defaultColumns);
const ORDER_STEP = 10;
const formInitValues = { menuName: '', component: '', menuPath: '' };
const formRef = ref();
const formState = reactive(formInitValues);
const [initValues, setInitValues] = useState(null);
const [expandedRowKeys, setExpandedRowKeys] = useState([]);
const [expandedAllKeys, setExpandedAllKeys] = useState([]);
const [menuTypeDisabled, setMenuTypeDisabled] = useState([]);
const [openAddModal, setOpenAddModal] = useState(false);
const [menuId, setMenuId] = useState(null);
const [openEditModal, setOpenEditModal] = useState(false);
const {
  sourceData, // 表格数据
  spinning: spinning,
  timer,
  onFetchData,
  onSearchData,
  onResetData,
  onRefreshData
} = useFetchData(fetchGetMenuTree);

onBeforeMount(() => {
  onFetchData();
});

const onExpandAll = () => {
  if (toValue(expandedAllKeys)?.length === 0) {
    const allKeys = arrayDeepFlat(toValue(sourceData)).map((v) => v.menuId);
    setExpandedAllKeys(allKeys);
  }

  const status = toValue(expandedRowKeys)?.length === toValue(expandedAllKeys)?.length;
  setExpandedRowKeys(status ? [] : toValue(expandedAllKeys));
};

const onOpenAddModal = (value) => {
  const data = {};
  if (value) {
    const childrenMenu = value?.children?.at(-1);
    data.parentName = value.menuName;
    data.parentId = value.menuId;
    data.orderNum = childrenMenu?.orderNum ? childrenMenu.orderNum + ORDER_STEP : 1;
    if (value.menuType === 'MENU') {
      data.menuType = 'MENU';
      setMenuTypeDisabled(['CATALOG']);
    }
  } else {
    const menu = toValue(sourceData)?.at(-1);
    data.parentName = '主目录';
    data.orderNum = menu?.orderNum + ORDER_STEP;
  }
  setInitValues(data);
  setOpenAddModal(true);
};

const onCloseAddModal = () => {
  setInitValues(null);
  setMenuTypeDisabled([]);
  setOpenAddModal(false);
};

const onOpenEditModal = (value) => {
  setMenuId(value.menuId);
  setOpenEditModal(true);
};

const onCloseEditModal = () => {
  setMenuId(null);
  setOpenEditModal(false);
};

const onAddMenu = async (value) => {
  value.parentId = toValue(initValues)?.parentId;
  await fetchAddMenu(value);
  setOpenAddModal(false);
  onRefreshData(true);
};

const onEditMenu = async (value) => {
  value.menuId = toValue(menuId);
  await fetchUpdateMenu(value);
  setOpenEditModal(false);
  onRefreshData(true);
};

const onReset = () => {
  onResetData();
  toValue(formRef).resetFields();
};

const onDelete = async (values) => {
  await fetchDeleteMenu(values);
  onRefreshData(true);
};
</script>

<style lang="scss" scoped></style>
